
/*
 * Copyright (C) 2009 Archie L. Cobbs. All rights reserved.
 *
 * $Id: EntityField.java 377 2010-03-11 20:50:18Z archie.cobbs $
 */

package org.dellroad.sidekar;

import org.dellroad.stuff.string.ParseContext;

/**
 * The {@code "sidekarEntity"} implicit field.
 *
 * <p>
 * This is the implicit field with name {@link Sidekar#ENTITY_FIELD_NAME} containing the
 * {@link Entity} of which each item is an instance.
 * </p>
 *
 * <p>
 * When indexed, this field will sort consistent with a pre-order depth first search on the
 * inheritance tree. So parent entities sort before child entities, and once an entity appears,
 * all of its descendant entities will appear before any as-yet-unseen siblings of that entity.
 * </p>
 *
 * <p>
 * Unlike normal fields, this field may be accessed even if the associated {@link Item} is detached.
 * </p>
 *
 * @see Item#getSidekarEntity
 * @see Database#getEntityField
 */
@SuppressWarnings("rawtypes")
public final class EntityField extends ImplicitField<Entity> {

    private final Schema schema;

    EntityField(Schema schema) {
        super(Sidekar.ENTITY_FIELD_NAME, Entity.class);
        this.schema = schema;
    }

    @Override
    public Entity<?> get(Item<?> item) {
        return item.getSidekarEntity();
    }

    @Override
    public void visit(FieldSwitch fieldSwitch) {
        fieldSwitch.caseEntityField(this);
    }

    @Override
    public String toString(Entity entity) {
        return entity.getName();
    }

    @Override
    public Entity<?> fromString(ParseContext ctx) {
        return this.schema.getEntity(ctx.matchPrefix("\\p{javaJavaIdentifierStart}[\\p{javaJavaIdentifierPart}]*").group());
    }
}

